import logging,random,re
from flask import current_app,g,make_response,request
from re import match
from iHome.models import User
from iHome.utils.captcha.captcha import captcha
from iHome import constants, db,redis_store
from flask import jsonify,session
from iHome.utils.response_code import RET
from . import verify_blu
from iHome.utils.commony import login_required



@verify_blu.route("/image_code")
def image_code():
    """图片验证"""

    # 获取参数
    cur = request.args.get('cur')
    pre = request.args.get('pre')

    #判空
    if not cur:
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    # 生成图片验证码
    name, text, image = captcha.generate_captcha()

    # 保存编号和其对应的图片验证码内容到redis
    try:
        # 删除之前保存的数据
        redis_store.delete('ImageCode_' + pre)
        # 保存图片验证码文本到redis中
        redis_store.set('Image_Code_' + cur, text, constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存验证码失败')

    #返回验证码图片
    response = make_response(image)
    response.headers['Content-Type'] = 'image/jpg'
    return response

@verify_blu.route('/sms_code', methods = ["POST"])
def sms_code():
    """发送短信验证 请求"""

    #1.获取参数
    data_dict = request.json
    mobile = data_dict.get("mobile")  #用户输入的手机号
    image_code = data_dict.get("image_code") #用户输入的图片验证码
    image_code_id = data_dict.get("image_code_id")  #uuid

    #2.判空
    if not all([ mobile,image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    #  验证用户输入的手机格式
    if not match(r"^1[3578]\d{9}$",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机格式不正确")

    #验证用户输入的图片验证码
    # 3. 从redis中获取真实的图片验证码
    try:
        real_image_code = redis_store.get("Image_Code_" + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库操作失败")
    # 验证码过期
    if not real_image_code:
        return jsonify(errno=RET.NODATA, errmsg="验证码过期")

    # 判断用户输入的图片验证码和真实的图片验证码是否一致, 如果不一致, 就return
    if image_code.lower() != real_image_code.decode().lower():
        return jsonify(errno=RET.DATAERR, errmsg="输入图片验证码错误")
    # 查询用户表,看手机是否已经存在
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询失败")

    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg="手机号码已经存在")

    # 发送短信验证码
    sms_code =random.randint(0, 999999)
    sms_code = '%06d' % sms_code
    print('短信验证码: %s' % sms_code)


    # 保存真实的短信验证码到redis中(以便后面注册函数中对比校验用户输入的短信验证码是否正确, 键名为手机号)
    try:
        redis_store.set("Sms_code_"+mobile, sms_code, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库操作失败")



    data= {
        "sms_code": sms_code
    }
    # 返回操作成功
    return jsonify(errno=RET.OK, errmsg="操作成功", data=data)



@verify_blu.route('/users',methods=["POST"])

def users():
    """注册功能"""

    #获取参数
    data_dict = request.json
    mobile = data_dict.get("mobile")
    phonecode = data_dict.get("phonecode")
    password = data_dict.get("password")

    #判空
    if not all([mobile, password, phonecode]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    #对比用户输入的短信验证码是否和redis中的短信验证码文本一致
    try:
         real_sms_code = redis_store.get("Sms_code_"+mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库操作失败")

    if not real_sms_code:
        return jsonify(errno=RET.NODATA, errmsg="验证码已经过期")
    if phonecode != real_sms_code.decode():
        return jsonify(errno=RET.DATAERR, errmsg="输入短信验证码错误")

    # 删除短信验证码
    try:
        redis_store.delete('SMSCode_'+mobile)
    except Exception as e:
        logging.error(e)

    # 将用户数据保存到数据库
    user = User(mobile=mobile, name=mobile)
    user.password = password

    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        logging.error(e)
        db.rollback()
        return jsonify(errno=RET.DATAEXIST, errmsg='手机号已存在')
        # 缓存到session
    session['user_id'] = user.id
    session['mobile'] = mobile
    session['name'] = mobile


    # 返回用户信息
    return jsonify(errno=RET.OK, errmsg='OK')



@verify_blu.route('/sessions',methods=["POST"])
def login():

    """登陆"""
    data_dict = request.json
    mobile = data_dict.get('mobile')
    password = data_dict.get('password')

    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    # 判断手机格式
    if not re.match(u"^1[34578]\d{9}$", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号格式不正确")

   # 查询用户表
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询错误')

      #判断是否有这个用户
    if user is None:
        return jsonify(errno=RET.USERERR, errmsg='用户不存在')

       #检查密码
    if not user.check_password(password):
        return jsonify(errno=RET.LOGINERR, errmsg='密码错误')

     #添加到session
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['name'] = user.name

    return jsonify(errno=RET.OK, errmsg='登录成功')


@verify_blu.route('/loginout',methods=['delete'])
@login_required
def loginout():
    """退出登陆"""
    # 判断是否登陆
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")


    #退出登录
    session.pop('name', None)
    session.pop('mobile', None)
    session.pop('user_id', None)

    return jsonify(errno=RET.OK, errmsg="OK")


@verify_blu.route('/session',methods=['GET'])
@login_required
def check_longin():
    # 判断是否登录
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    name = user.name
    user_id = session.get("user_id")

    if not name:
        return jsonify(errno=RET.SESSIONERR, errmsg='用户未登录')
    else:
        return jsonify(errno=RET.OK, errmsg='用户已登录', data={'name': name, 'user_id': user_id})



